package sys

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: 系统.菜单
*******************************************************************************/
import (
	"context"
	"permis/api/api"
	"permis/api/cache"
	"permis/model"

	gpc "gitee.com/cloudapex/protos/comm/pb"
	gpb "gitee.com/cloudapex/protos/permis/pb"

	"gitee.com/cloudapex/ulern/util"
)

/*
 * 描述: 菜单列表
 * 方法: Simple
 *********************************************************************/
func (this *Server) MenuList(ctx context.Context, req *gpb.MenuListReq) (*gpb.MenuListRes, error) {
	items, err := (&model.Power{
		CoId:   req.CoId,
		Name:   req.Name,
		Type:   model.EPower(req.Type),
		CMatch: req.Match,
		State:  req.State,
	}).Find()
	if err != nil {
		return nil, api.DBError("", err)
	}

	powers := []*gpb.Power{}
	if err := util.Convert(&powers, items); err != nil {
		return nil, api.ConvertError("", err)
	}
	return &gpb.MenuListRes{List: powers}, nil
}

/*
 * 描述: 菜单树表
 * 方法: Simple
 *********************************************************************/
func (this *Server) MenuTree(ctx context.Context, req *gpc.IdRequest) (*gpb.MenuTreeRes, error) {
	items, err := (&model.Power{CoId: req.Id}).FindTree()
	if err != nil {
		return nil, api.DBError("", err)
	}
	res := &gpb.MenuTreeRes{}
	if err := util.Convert(&res.List, items); err != nil {
		return nil, api.ConvertError("", err)
	}
	return res, nil
}

/*
 * 描述: 新增菜单
 * 方法: Simple
 *********************************************************************/
func (this *Server) MenuAdd(ctx context.Context, req *gpb.MenuAddReq) (*gpc.IdResponse, error) {
	p := &model.Power{Id: req.ParentId}
	if req.ParentId != 0 {
		if has, err := p.Load(); !has || err != nil {
			return nil, api.DBError("上级菜单不存在", err)
		}
		if p.CoId != req.CoId {
			return nil, api.Error(api.ECode_ParamsErr, "所属公司不一致", nil)
		}
	}

	m := model.Power{
		ParentId: req.ParentId,
		NodePath: model.NodePath(p.NodePath, p.Id),
		CoId:     req.CoId,
		Icon:     req.Icon,
		Name:     req.Name,
		Type:     model.EPower(req.Type),
		Match:    req.Match,
		Comp:     req.Comp,
		UrlPath:  req.UrlPath,
		Tntyp:    model.ETreeNode_Leaf,
		Order:    req.Order,
		State:    req.State,
		Remark:   req.Remark,
	}
	if _, err := m.Create(); err != nil {
		return nil, api.DBError("", err)
	}

	// 把父节点的Tntyp更新为Base
	if p.Tntyp == model.ETreeNode_Leaf {
		if _, err := (&model.Power{Tntyp: model.ETreeNode_Base}).Update(p.Id); err != nil {
			return nil, api.DBError("更新父级用户组类型失败", err)
		}
	}
	return &gpc.IdResponse{Id: m.Id}, nil
}

/*
 * 描述: 编辑菜单
 * 方法: Simple
 *********************************************************************/
func (this *Server) MenuUpd(ctx context.Context, req *gpb.MenuUpdReq) (*gpc.UnResponse, error) {
	old := model.Power{Id: req.Id}
	if has, err := old.Load(); !has || err != nil {
		return nil, api.DBError("此菜单不存在", err)
	}

	upd := model.Power{
		Id:      req.Id,
		Icon:    req.Icon,
		Name:    req.Name,
		Type:    model.EPower(req.Type),
		Match:   req.Match,
		Comp:    req.Comp,
		UrlPath: req.UrlPath,
		Order:   req.Order,
		State:   req.State,
		Remark:  req.Remark,
	}
	// 更新记录, 允许后面的几个字段被重置为默认值
	if _, err := upd.Update(req.Id, "icon", "order", "remark"); err != nil {
		return nil, api.DBError("此菜单不存在", err)
	}

	util.Goroutine("HandRouteRoles", func() { // 更新路由角色缓存
		if upd.Type != model.EPower_Func || old.Match == upd.Match {
			return
		}
		if err := cache.HandRouteRoles(req.CoId, []int64{req.Id}, true); err != nil {
			this.Error("MenuDel.HandUserRoles err:%v", err)
		}
		if err := cache.HandRouteRoles(req.CoId, []int64{req.Id}, false); err != nil {
			this.Error("MenuDel.HandUserRoles err:%v", err)
		}
	})
	return &gpc.UnResponse{}, nil
}

/*
 * 描述: 删除菜单
 * 方法: Simple
 *********************************************************************/
func (this *Server) MenuDel(ctx context.Context, req *gpc.CoXIdRequest) (*gpc.UnResponse, error) {
	eff, err := (&model.Power{}).Delete(req.XId)
	if err != nil {
		return nil, api.DBError("", err)
	}
	if eff == 0 {
		return nil, api.FoundError("此菜单不存在", err)
	}

	if _, err := (&model.RolePower{}).Delete(0, req.XId); err != nil {
		return nil, api.DBError("", err)
	}

	util.Goroutine("HandRouteRoles", func() { // 更新路由角色缓存
		if err := cache.HandRouteRoles(req.CoId, []int64{req.XId}, true); err != nil {
			this.Error("MenuDel.HandUserRoles err:%v", err)
		}
	})
	return &gpc.UnResponse{}, nil
}
